package exception;

import java.io.FileOutputStream;
import java.io.IOException;

/**
 * finally块
 * finally块是异常处理机制的最后一块,它可以直接跟在try后面或者最后一个
 * catch块后面.
 *
 * finally可以保证只要程序执行到try里面,无论try中的代码是否出现错误,
 * finally块内容都必定执行.
 *
 * 通常我们会将释放资源这类操作放在finally块中.例如IO操作后的close调用.
 */
public class FinallyDemo {
    public static void test1() {
        System.out.println("程序开始了");
        try {
            String line = "";
            System.out.println(line.length());
            /*
                try语句块中出错代码以下的内容都不会执行,例如:
                如果上面System.out.println(line.length());出现了
                空指针,那么程序会直接跳过下面的return来到catch.
             */
            return;
        } catch (Exception e) {
            System.out.println("出错了");
        } finally {
            System.out.println("finally块执行了");
        }
        System.out.println("程序结束了");
    }

    public static void test2() {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("files/fos.dat");
            fos.write(1);
        } catch (IOException e) {
            System.out.println("出错了");
        } finally {
            try {
                if(fos!=null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * finally块
     * finally块是异常处理机制的最后一块,它可以直接跟在try后面或者最后一个
     * catch块后面.
     *
     * finally可以保证只要程序执行到try里面,无论try中的代码是否出现错误,
     * finally块内容都必定执行.
     *
     * 通常我们会将释放资源这类操作放在finally块中.例如IO操作后的close调用.
     *
     *
     * finally相关面试题
     * 请说明:final,finally,finalize是什么?
     * final:
     * finally:参考FinallyDemo1的笔记
     * finalize:是定义在Object中的一个方法.该方法是一个对象生命周期中的最后
     * 一个方法.当GC发现一个对象没有引用时要将其回收释放资源,在释放前的最后一
     * 刻会调用该方法
     *
     *
     * 第二题下面代码所示
     * */
    public static void test3() {
        System.out.println(
                test("0")+","+test("")+","+test(null)
        );//3,3,3
    }

    private static int test(String str){
        try {
            return str.charAt(0)-'0';
        } catch (StringIndexOutOfBoundsException e) {
            return 1;
        } catch (NullPointerException e){
            return 2;
        } finally {
            return 3;
        }
    }

    public static void main(String[] args) {
        test1();
        test2();
        test3();
    }
}
